package com.acwing.partition3;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;

public class AC275传纸条 {
    
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));
        String[] s = reader.readLine().split("\\s+");
        int m = Integer.parseInt(s[0]), n = Integer.parseInt(s[1]);
        int[][] matrix = new int[m + 1][n + 1];
        for (int i = 1; i <= m; i++) {
            s = reader.readLine().split("\\s+");
            for (int j = 1; j <= n; j++) matrix[i][j] = Integer.parseInt(s[j - 1]);
        }
        // writer.write(dynamicProgramming(matrix, m, n) + "\n");
        int[][][] memo = new int[m + n + 1][m + 1][m + 1];
        for (int i = 0; i < memo.length; i++) {
            for (int j = 0; j < memo[i].length; j++) {
                Arrays.fill(memo[i][j], -1);
            }
        }
        writer.write(memoization(m + n, m, m, memo, matrix) + "\n");
        writer.flush();
    }

    private static int memoization(int k, int i, int j, int[][][] memo, int[][] matrix) {
        if (memo[k][i][j] >= 0) return memo[k][i][j];
        //初始状态，递归的出口
        if (k == 2 && i == 1 && j == 1) return memo[k][i][j] = matrix[i][j];
        if (i <= 0 || i >= k || j <= 0 || j >= k) return -0x3f3f3f3f;
        int val = i == j ? matrix[i][k - i] : matrix[i][k - i] + matrix[j][k - j];
        int res = max(memoization(k - 1, i - 1, j - 1, memo, matrix), memoization(k - 1, i - 1, j, memo, matrix), 
            memoization(k - 1, i, j - 1, memo, matrix), memoization(k - 1, i, j, memo, matrix));
        return memo[k][i][j] = res + val;
    }

    private static int dynamicProgramming(int[][] matrix, int m, int n) {
        int[][][] dp = new int[m + n + 1][m + 1][m + 1];
        for (int k = 2; k <= m + n; k++) {
            for (int i = 1; i <= m; i++) {
                for (int j = 1; j <= m; j++) {
                    int a = k - i, b = k - j;
                    if (a < 0 || a > n || b < 0 || b > n) continue;
                    int val = i == j ? matrix[i][a] : matrix[i][a] + matrix[j][b];
                    dp[k][i][j] = max(dp[k - 1][i - 1][j], dp[k - 1][i - 1][j - 1],
                        dp[k - 1][i][j - 1], dp[k - 1][i][j]) + val;
                }
            }
        }
        return dp[m + n][m][m];
    }

    private static int max(int... nums) {
        int answer = -0x3f3f3f3f;
        for (int num : nums) answer = Math.max(answer, num);
        return answer;
    }
}
